package com.sunchangpeng.client.nio;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class TimeClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(TimeClient.class);

    private Selector selector;

    public void start() {
        try {
            selector = Selector.open();
            socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(false);

            if (socketChannel.connect(new InetSocketAddress(host, port))) {
                socketChannel.register(selector, SelectionKey.OP_READ);
                byte[] req = "TIME".getBytes();
                ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
                writeBuffer.put(req);
                writeBuffer.flip();
                socketChannel.write(writeBuffer);
                if (!writeBuffer.hasRemaining()) {
                    LOGGER.info("send to server success.");
                }
            } else {
                socketChannel.register(selector, SelectionKey.OP_CONNECT);
            }

            while (!Thread.interrupted()) {
                selector.select();
                Set<SelectionKey> selectedKeys = selector.selectedKeys();

                for (SelectionKey selectionKey : selectedKeys) {
                    SocketChannel sc = (SocketChannel) selectionKey.channel();
                    if (selectionKey.isConnectable()) {
                        if (sc.finishConnect()) {
                            sc.register(selector, SelectionKey.OP_READ);
                            byte[] req = "TIME".getBytes();
                            ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
                            writeBuffer.put(req);
                            writeBuffer.flip();
                            socketChannel.write(writeBuffer);
                            if (!writeBuffer.hasRemaining()) {
                                LOGGER.info("send to server success.");
                            }
                        }
                    }

                    if (selectionKey.isReadable()) {
                        ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                        int readBytes = sc.read(readBuffer);
                        if (readBytes > 0) {
                            readBuffer.flip();
                            byte[] bytes = new byte[readBuffer.remaining()];
                            readBuffer.get(bytes);
                            String body = new String(bytes, "UTF-8");
                            LOGGER.info("Now is : {}", body);
                        } else {
                            selectionKey.cancel();
                            sc.close();
                        }
                    }
                }

                selectedKeys.clear();
            }
        } catch (IOException e) {
            LOGGER.error("", e);
        } finally {
            if (selector != null) {
                try {
                    selector.close();
                } catch (IOException e) {
                    LOGGER.error("", e);
                }
            }
        }
    }

    public void connect(String host, int port) throws IOException {
        SocketChannel sc = SocketChannel.open();
        sc.configureBlocking(false);

        if (sc.connect(new InetSocketAddress(host, port))) {
            sc.register(selector, SelectionKey.OP_READ);
        }
    }

    public void send(String input) {
    }
}
